package com.blockmeta.bbs.businesslibrary.widget;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.core.widget.NestedScrollView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.text.TextUtils;
import android.util.AttributeSet;
import com.blankj.utilcode.util.LogUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;

import com.blockmeta.bbs.baselibrary.base.app.BaseApp;
import com.blockmeta.bbs.baselibrary.utils.FormatUtil;
import com.blockmeta.bbs.baselibrary.utils.SecurityUtil;
import com.blockmeta.bbs.baselibrary.utils.SharedPreferenceUtil;
import com.blockmeta.bbs.businesslibrary.R;
import com.blockmeta.bbs.businesslibrary.arouter.RouterHelper;
import com.blockmeta.bbs.businesslibrary.arouter.RouterPath;
import com.blockmeta.bbs.businesslibrary.constant.Constant;
import com.blockmeta.bbs.businesslibrary.constant.NetConstant;
import com.blockmeta.bbs.businesslibrary.eventbus.MsgSuccess;
import com.blockmeta.bbs.businesslibrary.util.AccountHelper;
import com.blockmeta.bbs.businesslibrary.util.DeviceUtil;
import com.blockmeta.bbs.businesslibrary.util.RouterActivityHelper;
import com.tencent.smtt.export.external.interfaces.WebResourceRequest;
import com.tencent.smtt.export.external.interfaces.WebResourceResponse;
import com.tencent.smtt.sdk.CookieManager;
import com.tencent.smtt.sdk.CookieSyncManager;
import com.tencent.smtt.sdk.WebBackForwardList;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import static com.blankj.utilcode.util.ActivityUtils.startActivity;

public class WebViewContainer extends SwipeToRefreshLayout implements View.OnClickListener {

    private static final int EXPIRES_TIME = 30 * 60 * 1000;

    private static final int WEB_ERROR_CHECK = 1;

    private String m_url;

    private Map<String, String> m_headers;

    private NestWebView m_webView;
    private ProgressBar m_progressBar;
    private View m_emptyView;
    private WebviewListener m_listener;

    /**
     * 接受从外界动态绑定javascriptInterface，可以绑定多个
     */
    private HashMap<String, JavascriptInterface> mJsInterfaces = null;
    private boolean mEnableJsInterface = true;
    /**
     * 接受从外界动态设置cookie，可以设置多个域的cookie
     */
    private HashMap<String, String> mCookieMap = null;
    // 上次载入时间
    private long m_lastLoadTime;

    // 是否在detach的时候keep webview
    private boolean m_bKeepWebView;
    // show progress on top of webview
    private boolean m_bShowProgress;

    // 是否需要重新载入
    private boolean m_bNeedReloadAfterToken = true;

    private boolean m_bPageLoading;

    // 是否允许刷新
    private boolean m_bRefreshEnable = true;

    private boolean m_bNestScroll = false;

    // 是否对a标签的链接始终用新webview打开
    private boolean m_bOpenNewWebView;

    private boolean m_error;
    private Context mContext;

    public void setRefreshEnable(boolean refreshEnable) {
        this.m_bRefreshEnable = refreshEnable;
        setEnabled(refreshEnable);
    }

    public static interface WebviewListener {
        public void onPageStart(WebView webView, String url);

        public void onTitleReceived(String title);

        public boolean onShouldOverrideUrl(String url);
    }

    public WebViewContainer(Context context) {
        super(context);

        init(context);
    }

    public WebViewContainer(Context context, boolean isNested) {
        super(context);
        this.m_bNestScroll = isNested;
        init(context);
    }

    public WebViewContainer(Context context, AttributeSet attrs) {
        super(context, attrs);

        init(context);
    }

    public void setOpenNewWebView(boolean openNewWebView) {
        m_bOpenNewWebView = openNewWebView;
    }

    public void setKeepWebView(boolean keepWebView) {
        m_bKeepWebView = keepWebView;
    }

    public void setShowProgress(boolean pShowProgress) {
        m_bShowProgress = pShowProgress;
    }

    public void setZoomEnable(boolean zoomEnable) {
        WebSettings settings = m_webView.getSettings();
        settings.setDisplayZoomControls(false);
    }

    public void setWebviewListener(WebviewListener listener) {
        m_listener = listener;
    }


    public void callJavaScript(String call, String param) {
        m_webView.callJavaScript(call, param);
    }


    public void load(String url) {
        checkClearCache();

        m_url = url;
        m_webView.loadUrl(m_url, getWebCommonHeader(url));
        reload();
    }

    public Map<String, String> getWebCommonHeader(String url) {
        Map<String, String> headers = new HashMap<>();

        return headers;
    }

    public void loadData(String url, String content) {
        checkClearCache();

        m_webView.loadDataWithBaseURL(url, content, null, "utf-8", null);
        reload();
    }

    public void load(String url, Map<String, String> additionalHttpHeaders) {
        checkClearCache();

        m_url = url;
        m_headers = getWebCommonHeader(url);
        if (additionalHttpHeaders != null) {
            m_headers.putAll(additionalHttpHeaders);
        }

        m_webView.loadUrl(m_url, m_headers);
        reload();
    }

    public void script(String script) {
        m_webView.loadUrl(script);
    }

    public WebBackForwardList saveState(Bundle outState) {
        WebBackForwardList tWebBackForwardList = m_webView.saveState(outState);
        return tWebBackForwardList;
    }

    public WebBackForwardList restoreState(Bundle inState) {
        WebBackForwardList tWebBackForwardList = m_webView.restoreState(inState);
        return tWebBackForwardList;
    }

    public void setCacheMode(int cacheMode) {
        WebSettings settings = m_webView.getSettings();
        settings.setCacheMode(cacheMode);
    }

    public NestWebView getWebView() {
        return m_webView;
    }

    public boolean goBack() {
        if (m_webView.canGoBack()) {
            m_webView.goBack();
            reload();

            return true;
        }

        return false;
    }

    public WebBackForwardList getHistorys(){
        WebBackForwardList webBackForwardList = m_webView.copyBackForwardList();
        return webBackForwardList;
    }


    public String getUrl() {
        String url = m_webView.getUrl();
        if (TextUtils.isEmpty(url)) {
            url = m_url;
        }

        return url;
    }

    public void clearCache(boolean value) {
        m_webView.clearCache(value);
    }

    public void refresh() {
        checkClearCache();

        if (!TextUtils.isEmpty(m_webView.getUrl())) {
            m_webView.loadUrl(m_webView.getUrl());
        } else if (!TextUtils.isEmpty(m_url)) {
            m_webView.loadUrl(m_url);
        } else {
            return;
        }

        reload();
    }

    private void checkClearCache() {
        boolean webCache = SharedPreferenceUtil.getBoolean(BaseApp.getApp(), Constant.KEY_WEB_NO_CACHE, false);

        if (webCache) {
            m_webView.clearCache(false);
        }
    }


    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();

        if (!m_bKeepWebView) {
            m_webView.getSettings().setJavaScriptEnabled(true);
            m_webView.setVisibility(GONE);
            m_webView.destroy();

            removeView(m_webView);
        }

        EventBus.getDefault().unregister(this);
    }

    private void showLoading() {
        m_error = false;
        m_emptyView.setVisibility(INVISIBLE);
        m_progressBar.setVisibility(m_bShowProgress ? VISIBLE : INVISIBLE);
    }

    private void reload() {
        m_lastLoadTime = System.currentTimeMillis();

        showLoading();
    }

    private void init(Context context) {
        mContext = context;
        RelativeLayout view = (RelativeLayout) LayoutInflater.from(context).inflate(
                R.layout.webview_container, this).findViewById(R.id.webview_container);

        m_progressBar = (ProgressBar) view.findViewById(R.id.webview_progressBar);
        m_emptyView = view.findViewById(R.id.webview_empty);

//        m_bRefreshEnable = false;
        setEnabled(m_bRefreshEnable);

        m_emptyView.findViewById(R.id.webview_refresh).setOnClickListener(this);

        m_webView = new NestWebView(context);
        m_webView.setWebViewClient(new CustomWebClient());
        m_webView.setWebChromeClient(new CustomWebChromeClient());
        m_webView.setOnScrollListener(mOnScrollListener);


        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);

        if (m_bNestScroll) {
            NestedScrollView nsv = new NestedScrollView(context);
            nsv.setFillViewport(true);
            nsv.addView(m_webView, params);
            view.addView(nsv, 0, params);
        } else {
            view.addView(m_webView, 0, params);
        }

        m_bShowProgress = true;

        setOnRefreshListener(mOnRefreshListener);

    }


    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.webview_refresh) {
            refresh();
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        EventBus.getDefault().register(this);
        m_webView.reload();
        m_webView.getSettings().setJavaScriptEnabled(true);
    }

    //登入信息改变
    @Subscribe(threadMode = ThreadMode.MAIN) //在ui线程执行
    public void onEvent(MsgSuccess message) {
//        if (message.login.equals("LOGIN") && AccountHelper.isLogin() && AccountHelper.getUserPhonePOJO() != null) //登陆成功
//        {
//
//        }else if(message.login.equals("LOGIN") && !AccountHelper.isLogin()){
//            //绑定IM 广播和服务
//            LogUtils.d("author" + " LoginUI(loginout message)");
//        }
        if (m_bNeedReloadAfterToken) {
            post(new Runnable() {
                @Override
                public void run() {
                    LogUtils.i("lianzuo", "onevent login" + (AccountHelper.isLogin() ? "in" : "out"));
                    String url = NetConstant.CHAIN_THING_URL;
                    if(m_url.contains(NetConstant.CHAIN_THING_URL)){
                        url = NetConstant.CHAIN_THING_URL;
                    }
                    synCookies(mContext, url, "");
                    refresh();
                }
            });
        }
    }

    //    网络链接改变，需要刷新
    @Subscribe(threadMode = ThreadMode.MAIN) //在ui线程执行
    public void onEvent(NetChangeEvent event) {
        if (m_error) {
            if (event.m_hasConnected) {
                refresh();
            }
        }
    }

    /**
     * 用于换头部
     *
     * @param title
     */
    private void doReceivedTitle(String title) {
        if (m_listener == null) {
            return;
        }

        if (title != null && title.length() > 0
                && title.indexOf(".htm") == -1
                && title.indexOf(".shtm") == -1) {
            m_listener.onTitleReceived(title);
        }
    }

    private void doPageFinish() {
        if (m_error) {
            return;
        }

        m_progressBar.setVisibility(INVISIBLE);
        m_emptyView.setVisibility(INVISIBLE);
        m_webView.setVisibility(VISIBLE);
    }

    private void showEmptyView(boolean error) {
        if (error) {
            m_error = error;
        }

        m_emptyView.setVisibility(VISIBLE);
        m_webView.setVisibility(INVISIBLE);
        m_progressBar.setVisibility(INVISIBLE);
    }

    SwipeRefreshLayout.OnRefreshListener mOnRefreshListener = new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            reload();
            refresh();
            setRefreshing(false);
        }
    };

    private NestWebView.OnScrollChangedListener mOnScrollListener = new NestWebView.OnScrollChangedListener() {
        @Override
        public void onScrollChanged(int left, int top, int oldLeft, int oldTop) {
//            LogUtils.d("lianzuo","container onScrollChanged l" + left + " t" + top + " oldl" + oldLeft + "oldt" + oldTop);
            if (top == 0 && m_bRefreshEnable && !m_bPageLoading) {
                setEnabled(true);
            } else {
                setEnabled(false);
            }
        }
    };

    private class CustomWebClient extends NestWebViewClient {

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
//            LogUtils.i("lianzuo", "onPageStarted url: " + url);
            super.onPageStarted(view, url, favicon);
            m_bPageLoading = true;
            if (m_listener != null) {
                m_listener.onPageStart(view, url);
            }
        }

        @Override
        public void onPageFinished(WebView view, String url) {
//            LogUtils.i("lianzuo", "onPageFinished url: " + url);
            super.onPageFinished(view, url);
            m_bPageLoading = false;
            if (Build.VERSION.SDK_INT >= 19) {
                doReceivedTitle(view.getTitle());
            }

            doPageFinish();
        }

        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest webResourceRequest) {
//            LogUtils.i("lianzuo", "shouldInterceptRequest url: " + webResourceRequest.getUrl());
            String url = webResourceRequest.getUrl().toString();
            //如果是内部页面，可通过okhttp加载网络资源
            return super.shouldInterceptRequest(view, webResourceRequest);
        }

        /**
         * 4.* webview 兼容
         *
         * @param view
         * @param url
         * @return
         */
        @Override
        public WebResourceResponse shouldInterceptRequest(final WebView view, final String url) {

//            LogUtils.i("lianzuo", "shouldInterceptRequest url: " + url);
//            if (!url.startsWith("http") && isDeepLink(url)) {
//                post(new Runnable() {
//                    @Override
//                    public void run() {
//                        doDeepLink(view, url);
//                    }
//                });
//
//                return new WebResourceResponse("", "", new ByteArrayInputStream(new byte[0]));
//            }

            return super.shouldInterceptRequest(view, url);
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {

//            LogUtils.i("lianzuo", "shouldOverrideUrlLoading url: " + url);
            if (url.contains("needlogin=1")) {
                //跳转到登陆页面
                if (!AccountHelper.isLogin()) {
                    RouterHelper.startActivity(mContext, RouterPath.PHONE_LOGIN_ACTIVITY);
                }
            } else if (url.endsWith("#new_blank")) {
                //新窗口打开
//                RouterHelper.startActivity(mContext, RouterPath.WEB_ACTIVITY,url);
                RouterActivityHelper.openNewWeb(mContext, url);
            }else if (isDeepLink(url)) {
                doDeepLink(view, url);
            }
            else if (url.startsWith("alipays://platformapi/startApp?") ||
                    url.startsWith("weixin://wap/pay?")) {
                Intent intent;
                try {
                    intent = new Intent();
                    intent.setAction(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse(url));
                    startActivity(intent);
                } catch (Exception e) {
                    //e.printStackTrace();
                }
            } else if (url.contains("platformapi/startapp")) {
                Intent intent;
                try {
                    intent = Intent.parseUri(url,
                            Intent.URI_INTENT_SCHEME);
                    intent.addCategory(Intent.CATEGORY_BROWSABLE);
                    intent.setComponent(null);
                    startActivity(intent);
                } catch (Exception e) {
                    //e.printStackTrace();
                }
            }
            ///< android  6.0 两种方式获取intent都可以跳转支付宝成功,7.1测试不成功
            else if ((Build.VERSION.SDK_INT > Build.VERSION_CODES.M)
                    && (url.contains("platformapi") && url.contains("startapp"))) {
                Intent intent;
                try {
                    intent = Intent.parseUri(url,
                            Intent.URI_INTENT_SCHEME);
                    intent.addCategory(Intent.CATEGORY_BROWSABLE);
                    intent.setComponent(null);
                    startActivity(intent);
                } catch (Exception e) {
                    //e.printStackTrace();
                }
            } else {
                //执行外部回调
                if(m_listener != null && m_listener.onShouldOverrideUrl(url)){
                    return true;
                }

                //打开url
                if (m_bOpenNewWebView) {
                    //新窗口打开
                    RouterActivityHelper.openNewWeb(mContext, url);
                } else {
                    return super.shouldOverrideUrlLoading(view, url);
//                    load(url);
                }
            }
            return true;
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            LogUtils.i("lianzuo", "onReceiveError" + errorCode + failingUrl);
            if (failingUrl.equalsIgnoreCase(view.getUrl())) {
                showEmptyView(true);
            }
            super.onReceivedError(view, errorCode, description, failingUrl);
        }

    }


    private class CustomWebChromeClient extends NestWebChromeClient {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);

            if (m_bShowProgress) {
                if (newProgress < 100) {
                    m_progressBar.setVisibility(VISIBLE);
                } else {
                    m_progressBar.setVisibility(INVISIBLE);
                }

                m_progressBar.setProgress(newProgress);
            }
        }

        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);

            doReceivedTitle(title);
        }
    }

    public static class Event_TokenUpdate {
        public Event_TokenUpdate() {
        }
    }

    public static class NetChangeEvent {
        public boolean m_hasConnected;
        public String m_netType;

        public NetChangeEvent(boolean hasConnected, String netType) {
            m_hasConnected = hasConnected;
            m_netType = netType;
        }
    }


    private void addJavascriptInterface() {
        if (!mEnableJsInterface) {
            return;
        }
        if (mJsInterfaces == null) {
            mJsInterfaces = new HashMap<String, JavascriptInterface>();
        }

        // 增加javascript接口的支持
        Iterator<String> it = mJsInterfaces.keySet().iterator();
        while (it.hasNext()) {
            String key = it.next();
            Object jsInterface = mJsInterfaces.get(key).createJsInterface(mContext);
            m_webView.addJavascriptInterface(jsInterface, key);
        }
    }

    private void removeJavascriptInterface() {
        if (mJsInterfaces == null) {
            mJsInterfaces = new HashMap<String, JavascriptInterface>();
        }

        // 增加javascript接口的支持
        Iterator<String> it = mJsInterfaces.keySet().iterator();
        while (it.hasNext()) {
            String key = it.next();
            m_webView.removeJavascriptInterface(key);
        }
    }

    public void addJsInterfaces(HashMap<String, JavascriptInterface> jsInterfaces) {
        mJsInterfaces = jsInterfaces;
        addJavascriptInterface();
    }

    public void setEnableJsInterface(boolean enableJsInterface) {
        if (mEnableJsInterface != enableJsInterface) {
            mEnableJsInterface = enableJsInterface;
            if (enableJsInterface) {
                addJavascriptInterface();
            } else {
                removeJavascriptInterface();
            }
        }
    }

    /**
     * 设置Cookie
     *
     * @param context
     * @param url
     * @param cookie
     */
    public void synCookies(Context context, String url, String cookie) {
        Uri uri = Uri.parse(url);
        String host = uri.getHost();

        CookieSyncManager.createInstance(context);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(true);
        //cookies是在HttpClient中获得的cookie
        if (!TextUtils.isEmpty(cookie)) {
            setCookie(cookieManager, host, cookie);
        }
        String uid = AccountHelper.getUid();
        if (!TextUtils.isEmpty(uid)) {
            setCookie(cookieManager, host, "uid=" + uid);
        }else {
            setCookie(cookieManager, host, "uid=");
        }
        String token = AccountHelper.getToken();
        if (TextUtils.isEmpty(token)){
            token = SharedPreferenceUtil.getString(mContext, Constant.TOKEN, "");
        }
        if (!TextUtils.isEmpty(token) && !TextUtils.isEmpty(uid)) {
            String currentTime = FormatUtil.getTimetoHMS(System.currentTimeMillis(), "yyyyMMdd");
            final String md5 = SecurityUtil.MD5(currentTime + "_eCM1_appcooike");
            setCookie(cookieManager, host, md5 + "=" + token);
            setCookie(cookieManager, host, "token=" + token);
        }else {
            setCookie(cookieManager, host, "token=");
        }

        String deviceId = DeviceUtil.getIMEI();
        if (!TextUtils.isEmpty(deviceId)) {
            setCookie(cookieManager, host, "device_id=" + deviceId);
        }

        String s = "Domain=" + uri.getHost();
        String s1 = "Path=/";
        setCookie(cookieManager, host, s);
        setCookie(cookieManager, host, s1);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
            CookieManager.getInstance().flush();
        } else {
            CookieSyncManager.getInstance().sync();
        }
    }

    private void setCookie(CookieManager cookieManager, String host, String value){
        cookieManager.setCookie(host, value);
        LogUtils.d("webview setcookie "+ host + " " + value);
    }

    public interface JavascriptInterface {
        Object createJsInterface(Context context);
    }

    //判断是否安装支付宝app
    public static boolean checkAliPayInstalled(Context context) {

        Uri uri = Uri.parse("alipays://platformapi/startApp");
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        ComponentName componentName = intent.resolveActivity(context.getPackageManager());
        return componentName != null;
    }

    // 调起支付宝并跳转到指定页面
    private void startAlipayActivity(String url) {
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        startActivity(intent);

//        Intent intent;
//        try {
//            intent = Intent.parseUri(url,
//                    Intent.URI_INTENT_SCHEME);
//            intent.addCategory(Intent.CATEGORY_BROWSABLE);
//            intent.setComponent(null);
//            startActivity(intent);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

}
